package com.keyware.kd.controller.login;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import cn.zifangsky.license.LicenseVerify;
import com.keyware.kd.service.itf.auditlog.UserAuditLogService;
import com.keyware.kd.vo.menu.menuVo;
import com.keyware.utils.ProjectIdentNew;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.keyware.kd.context.Token;
import com.keyware.kd.controller.BaseController;
import com.keyware.kd.listener.SessionCounter;
import com.keyware.kd.repository.entity.UserSecret;
import com.keyware.kd.repository.entity.department.Department;
import com.keyware.kd.repository.entity.number.NumberBuilder;
import com.keyware.kd.repository.entity.safemanagement.SafeManagement;
import com.keyware.kd.repository.entity.user.User;
import com.keyware.kd.service.itf.department.DepartmentService;
import com.keyware.kd.service.itf.jurisdiction.MenuService;
import com.keyware.kd.service.itf.number.NumberBuilderService;
import com.keyware.kd.service.itf.safemanagement.SafeManagementService;
import com.keyware.kd.service.itf.user.UserService;
import com.keyware.kd.service.itf.usersecret.UserSecretService;
import com.keyware.kd.task.util.ClientUtil;
import com.keyware.kd.utils.Constant;
import com.keyware.kd.vo.user.UserVo;
import com.keyware.utils.DateUtils;
import com.keyware.utils.JsonUtils;
import com.keyware.utils.keycloud.Json;
import com.keyware.utils.keycloud.LicenseUtil;


@Controller
public class LoginController extends BaseController {
	
	public static Logger logger = Logger.getLogger(LoginController.class);
	
	public static String NEED_VALIDATE_2 = "NEED_VALIDATE_2";//session中的值：二次验证
	public static String USERNAME = "USERNAME";//session中的值：登陆名
	public static String VALIDATE_2_TOKEN = "VALIDATE_2_TOKEN";//session中的值：二次验证token
	public static String ERROR_MESSAGE = "ERROR_MESSAGE";//session中的值：错误信息
	
	
	@Resource
	private UserService userService;
	
	@Resource
	private DepartmentService departmentService;
	
	@Autowired
	private MenuService menuService;
	
	@Resource
	private SafeManagementService safeManagementService;

	@Autowired
	private NumberBuilderService numberBuilderService;

	@Autowired
	private UserAuditLogService userAuditLogService;
	@Autowired
	private UserSecretService userSecretService;
	

	
	/**
	 * 
	 * @Title: indexPage
	 * @Description: 登录
	 * @return
	 * @return String
	 */
	@RequestMapping(value = {"/index" })
	@Token(create=true)
	public String indexPage(){
		//获取项目类型对应的参数
		Properties properties = numberBuilderService.getProjectTypeParameter();
		if(properties != null){
			@SuppressWarnings("rawtypes")
			Enumeration enum1 = properties.propertyNames();//得到配置文件的名字
			while(enum1.hasMoreElements()) {
			    String strKey = (String) enum1.nextElement();
			    String strValue = properties.getProperty(strKey);
			    request.getSession().setAttribute(strKey, strValue);    
			}
		}

		//当前项目的版本号
		request.setAttribute("projectVersion",Constant.PROJECT_VERSION);

		if("0".equals(Constant.sessionCount))
			request.setAttribute("sessionConuntDescribe","不限制并发数!");
		else
			request.setAttribute("sessionConuntDescribe","限制最大并发数为"+Constant.sessionCount);

		return Constant.projectName+"/portal/indexPage";
	}
	
	
	/**
	 * 
	 * @Title: submit
	 * @Description: 登录验证
	 * @param uservo
	 * @return
	 * @return ModelAndView
	 */
	@Token(validate=true)
	@RequestMapping(value = "/login",produces = "application/json; charset=utf-8")
	public ModelAndView submit(@ModelAttribute UserVo uservo){
		ModelAndView modelAndView = new ModelAndView("redirect:/portal");
        //授权验证
		LicenseVerify licenseVerify = new LicenseVerify();
		//校验证书是否有效
		/*boolean verifyResult = licenseVerify.verify();
		if(!verifyResult){
			request.getSession().setAttribute(ERROR_MESSAGE,"您的证书无效，请核查服务器是否取得授权或重新申请证书！");//重新授权
			logger.error("您的证书无效，请核查服务器是否取得授权或重新申请证书！");
			return modelAndView;
		}*/

		//项目初期不验证验证码
		/*//从session中取出servlet生成的验证码text值  
		String kaptchaExpected = (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);  
		//校验验证码是否正确  
		if (uservo.getKaptcha() == null || !uservo.getKaptcha().equalsIgnoreCase(kaptchaExpected)){  
			request.getSession().setAttribute(ERROR_MESSAGE, "验证码错误");
			return modelAndView;
		}*/
		
		User tempUser = null;
		//从cookie中取得用户
		User user = userService.getCurrentUser();
		if(user == null){
			String sessionId = request.getSession(true).getId();
			boolean isRemember = StringUtils.isNotBlank(uservo.getIsRemember()) ? true :false;
			try {
				userService.login(uservo.getUserId(),uservo.getPassword(),isRemember,ClientUtil.getIP(request),sessionId);
			} catch (Exception e) {
				logger.error(e);
				//登陆错误信息
				request.getSession().setAttribute(ERROR_MESSAGE, e.getMessage());//登录信息有误
				return modelAndView;
			}
		}else{
			request.getSession().setAttribute(ERROR_MESSAGE, "已经登录");
		}
		if(Constant.projectName.equals("keyCloud")){
			LicenseUtil licenseUtil = new LicenseUtil();
			try {
				Json verification = licenseUtil.getVerification(request, uservo.getUserId());
				if(!verification.isSuccess()){
					request.getSession().setAttribute(ERROR_MESSAGE,verification.getMsg());
					return modelAndView;
				}
			} catch (Exception e) {
				logger.error(e);
				request.getSession().setAttribute(ERROR_MESSAGE, e.getMessage());//登录信息有误
				return modelAndView;
			}
			
		}
		tempUser = userService.selectUserByUserId(uservo.getUserId());
		request.getSession().setAttribute("user", tempUser);
		request.getSession().setAttribute("userId", tempUser.getUserId());
		request.getSession().setAttribute("user_id", tempUser.getId());	
		request.getSession().setAttribute("userName", tempUser.getUserName());
		//获取客户标识
		String  customer = numberBuilderService.getCustomerId();
		request.getSession().setAttribute("customCode", customer);
		String departName="";
		Department department= departmentService.selectByPrimaryKey(tempUser.getDepartId());
		if(department!=null){
			departName=department.getDeptName();
		}
		request.getSession().setAttribute("departName", departName);
		//密级
		UserSecret Secret = userSecretService.selectByPrimaryKey(tempUser.getId());
		if(Secret != null){
			request.getSession().setAttribute("secret", Secret.getSecret());
		}
		return modelAndView;
	}
	
	/**
	 * 
	 * @Title: portal
	 * @Description: 去登录页
	 * @return
	 * @return ModelAndView
	 */
	@RequestMapping(value = "/portal",method = RequestMethod.GET,produces = "application/json; charset=utf-8")
	public ModelAndView portal(){
		String errorMessage = (String)request.getSession().getAttribute(ERROR_MESSAGE);
		//ModelAndView mav = new ModelAndView("portal/indexPage");
		ModelAndView mav = new ModelAndView();
		mav.setViewName(Constant.projectName+"/portal/indexPage");
		
		mav.addObject("errorMessage",errorMessage);

		//当前项目的版本号
		mav.addObject("projectVersion",Constant.PROJECT_VERSION);

		if("0".equals(Constant.sessionCount))
			mav.addObject("sessionConuntDescribe","不限制并发数!");
		else
			mav.addObject("sessionConuntDescribe","限制最大并发数为"+Constant.sessionCount);

		request.getSession().removeAttribute(ERROR_MESSAGE);
		
		try {
			User user = (User)request.getSession(true).getAttribute("user");
			
			if(null != request.getAttribute("token"))
				mav.addObject("token",request.getAttribute("token"));
			
			if(user != null){
				return new ModelAndView("redirect:/loginSuccess");
			}
			
		} catch (Exception e) {
			logger.error(e);
			return mav;
		}
		return mav;
	}
	
	
	/**
	 * 登陆成功
	 * @return
	 */
	@RequestMapping(value="/loginSuccess",method = RequestMethod.GET)
	public String loginSuccess(){
		String loginIp = request.getRemoteAddr();
		//取消如果队列中存在相同的IP 则SESSION不增加
    boolean rs = true;
    	if(SessionCounter.list != null && SessionCounter.list.size()>0){
    		for(int i = 0;i < SessionCounter.list.size(); i ++){
    			if(loginIp.equals(SessionCounter.list.get(i))){
    				rs = false;
    			}
    		}
    	}
    	if(rs){
    		SessionCounter.list.add(loginIp);
    	}
    		/*SessionCounter.list.add(loginIp);
    		SessionCounter.sessionIpMap.put(request.getSession().getId(), loginIp);
    		SessionCounter.activeSessions++;
    		logger.info("新增SESSION,sessionId = " + request.getSession().getId()
    				+ "; loginIp = " + loginIp +"; 当前总SESSION值为 "+SessionCounter.activeSessions);
    	}else{
    		if(SessionCounter.activeSessions == 0)
    			SessionCounter.activeSessions++;
    	}*/
		
		SessionCounter.sessionIpMap.put(request.getSession().getId(), loginIp);
		SessionCounter.activeSessions++;
		logger.info("新增SESSION,sessionId = " + request.getSession().getId()
				+ "; loginIp = " + loginIp +"; 当前总SESSION值为 "+SessionCounter.activeSessions);
		userAuditLogService.insertLog("登录", "登录", getUser_idFormSession("userName")+"登陆平台", request);

		return Constant.projectName+"/portal/loginSuccess";
	}
	
	
	@RequestMapping(value="/home",method = RequestMethod.GET)
	public ModelAndView home(){
		HttpSession session = request.getSession();
		String type = (String) session.getAttribute("type") == null?"":(String) session.getAttribute("type") ;
		String  customer = numberBuilderService.getCustomerId();
		ModelAndView mav = new ModelAndView();
		mav.setViewName(Constant.projectName+"/portal/home");
		User user = (User) request.getSession().getAttribute("user");
		String userInactiveType = "";
		if(!"admin".equals(user.getUserId()) && !"safesecret".equals(user.getUserId()) && !"safeaudit".equals(user.getUserId()) && !"sysadmin".equals(user.getUserId())){
			//获取当前设置的平台密级
			NumberBuilder numberBuilder = numberBuilderService.selectByPrimaryKey("platformPwdLevel");
			List<SafeManagement> safeManagements=null;
			SafeManagement safeManagement=null;
			if(null==numberBuilder || numberBuilder.getNumber().equals("platform")){//平台密级
				safeManagements = safeManagementService.selectInfo();//获取当前平台最小密级
				safeManagement = safeManagements.get(0);
			}else{//用户密级
				List<SafeManagement> safeManagementList = safeManagementService.selectAll();
				String userRankId = user.getUesrRankId() == null ? "" : user.getUesrRankId();
				if(!userRankId.equals("") && safeManagementList.size() > 0){
					for(SafeManagement safeManagement2 : safeManagementList){
						if(userRankId.equals(safeManagement2.getId())){
							safeManagement = safeManagement2;
						}
					}
				}
				if(safeManagement==null){
					safeManagements = safeManagementService.selectInfo();//获取当前平台最小密级
					safeManagement = safeManagements.get(0);
				}
			}
			//安全验证,提示密码过期
			//密码密码时间(天)
			long pwdChangeCycle =safeManagement.getPwdChangeCycle().multiply(new BigDecimal(24)).multiply(new BigDecimal(60)).longValue();
			String userPwdModifTime = user.getUserPwdModifTime();
			String flag = "false";
			//确保之前数据可以转换成功
			if(null!=userPwdModifTime && userPwdModifTime.length()<15){
				userPwdModifTime+=" 00:00";
			}
			if(null!=userPwdModifTime && userPwdModifTime.length()==19){
				userPwdModifTime=userPwdModifTime.substring(0,15);
			}
			long betweenDays = DateUtils.calculateTimeDifferenceByCalendar(userPwdModifTime,  DateUtils.getDate("yyyy-MM-dd HH:mm"));
			if(betweenDays > pwdChangeCycle){
				flag = "true";
				request.setAttribute("updateMessage", flag);
			}
			if(ProjectIdentNew.tianjin712.equals(customer) && !flag.equals("true") && !type.equals("1")){
				long expirationMin = safeManagement.getPwdExpirationTime().multiply(new BigDecimal(24)).multiply(new BigDecimal(60)).longValue();//失效时长(分钟)
				long betweeTimes = expirationMin - betweenDays;
			    if(expirationMin > betweenDays &&  betweeTimes <= 1440){
					flag = "true";
					request.setAttribute("updateMessage", flag);
					request.setAttribute("custom", customer);
					String userId=session.getAttribute("userId").toString();
					request.setAttribute("userId", userId);
					Long pwdMinLength=(long) 0;
					Long pwdMaxLength=(long) 0;
					if(safeManagement!=null){
						pwdMinLength=safeManagement.getMinimumPwdLength();
						pwdMaxLength=safeManagement.getMaximumPwdLength();
					}
					request.setAttribute("pwdMinLength",pwdMinLength );
					request.setAttribute("pwdMaxLength", pwdMaxLength);
				}
			}
			//验证用户是否超出非活跃时间
			if (!user.getUserId().equals("admin") && safeManagement != null && safeManagement.getUserInactiveTime() != null && !"".equals(safeManagement.getUserInactiveTime())) {
				//获取非活跃时间限定值(天)
				BigDecimal userInactiveTime = safeManagement.getUserInactiveTime();
				//获取上一次退出的时间
				String exitTime = user.getExitTime();
				//本次登录的时间-上一次退出时间=非活动时间范围是否大于限定值
				if (userInactiveTime != null && userInactiveTime.intValue() != 0) {
					long userInactiveTimeMin = userInactiveTime.multiply(new BigDecimal(24)).multiply(new BigDecimal(60)).longValue();//非活跃时间限定值(分钟)
					//确保之前数据可以转换成功
					if (null != exitTime && exitTime.length() < 15) {
						exitTime += " 00:00";
					}
					if (null != exitTime && exitTime.length() == 19) {
						exitTime = exitTime.substring(0, 15);
					}
					long between_days = DateUtils.calculateTimeDifferenceByCalendar(exitTime, DateUtils.getDate("yyyy-MM-dd HH:mm"));
					//判断非活动时间范围是否大于限定值
					if (between_days > userInactiveTimeMin) {
						 userInactiveType = "true";
					}else {
						//更新退出时间
						user.setExitTime(DateUtils.getDate("yyyy-MM-dd HH:mm"));
						userService.updateByPrimaryKey(user);
					}
				}
			}
		}

		//获取项目类型对应的参数
		Properties properties = numberBuilderService.getProjectTypeParameter();
		if(properties != null){
			@SuppressWarnings("rawtypes")
			Enumeration enum1 = properties.propertyNames();//得到配置文件的名字
			while(enum1.hasMoreElements()) {
			    String strKey = (String) enum1.nextElement();
			    String strValue = properties.getProperty(strKey);
			    request.getSession().setAttribute(strKey, strValue);    
			}
		}
		
		//带权限相关
		String userId = (String)SecurityUtils.getSubject().getPrincipal();//获取用户账户		
		//所有一级权限
		menuVo menuVo = new menuVo();
		menuVo.setUserId(userId);
		menuVo.setMenuLevel(1L);
		menuVo.setProjectSource(Constant.projectName);
		if("sysadmin".equals(userId)){
			menuVo.setIsSys("sysadmin");
		}

		List<menuVo> menusParents = menuService.listSingleLevelMenu(menuVo);
		//List 去重复项
		List<menuVo> removeDuplicate = this.removeDuplicate(menusParents);

		//712屏蔽质量统计分析
		for (int i=0;i<removeDuplicate.size();i++){
			if (ProjectIdentNew.tianjin712.equals(customer)&&"质量统计分析".equals(removeDuplicate.get(i).getMenuName())){
				removeDuplicate.remove(i);
			}
		}
		
		//如果不是超管 就不显示菜单和权限
		List<menuVo> listMenu = new ArrayList<menuVo>();
		if("admin".equals(getUser_idFormSession("userId"))){
			for(menuVo menu:removeDuplicate){
				if(!"安全管理".equals(menu.getMenuName())){
					if(ProjectIdentNew.tianjin712.equals(customer)){
						if(!"审计管理".equals(menu.getMenuName())){
							listMenu.add(menu);
						}
					}else{
						listMenu.add(menu);
					}
				}
			}
			request.setAttribute("menuParents", JsonUtils.toJson(listMenu));
		}else{
			if((!"sysadmin".equals(getUser_idFormSession("userId")))&&(!"admin".equals(getUser_idFormSession("userId")))&&(!"safesecret".equals(getUser_idFormSession("userId")))&& (!"safeaudit".equals(getUser_idFormSession("userId")))){
				for(menuVo menu:removeDuplicate){
					if((!"安全管理".equals(menu.getMenuName())) && (!"审计管理".equals(menu.getMenuName()))){
						listMenu.add(menu);
					}
				}
				request.setAttribute("menuParents", JsonUtils.toJson(listMenu));
			}else{
				request.setAttribute("menuParents", JsonUtils.toJson(removeDuplicate));
			}
		}
		//用户名
		request.setAttribute("userName", user.getUserName());
		//非活跃状态
		request.setAttribute("userInactiveType", userInactiveType);
		return mav;
	}
	
	/**
	 * 
	 * @Title: logout
	 * @Description: 注销 返回登陆页面
	 * @return
	 * @return String
	 */
	@RequestMapping(value="/logout",method = {RequestMethod.GET, RequestMethod.POST},produces = "application/json; charset=utf-8")
	public String logout(){
		try {
			String user_id = getUser_idFormSession("user_id");

			userAuditLogService.insertLog("注销", "注销", getUser_idFormSession("userName")+"执行注销操作", request);

			userService.logout(user_id);
			//清理session记录
			cleanSessionRecord();	
		} catch (Exception e) {
			logger.error(e);
			e.printStackTrace();
		}
		return "redirect:/index";
	}
	
	
	private void cleanSessionRecord() {
		String secctionId = request.getSession().getId();
		String loginIp = request.getRemoteAddr();
        if(SessionCounter.activeSessions>0){
            if(SessionCounter.list.size() > 0){
                for(int i = 0;i < SessionCounter.list.size(); i ++){
                    if(loginIp.equals(SessionCounter.list.get(i))){
                    	SessionCounter.list.remove(i);  
                    }
                }
            }
            SessionCounter.sessionIpMap.remove(secctionId);
            SessionCounter.activeSessions--;//在用户销毁的时候,从队列中踢出这个IP
			logger.info("销毁SESSION,sessionId = " + secctionId
                             + "; loginIp = " + loginIp +"; 当前总SESSION值为 "+SessionCounter.activeSessions);
        }
	}


	@RequestMapping(value="/logout/closewindows",method = {RequestMethod.GET, RequestMethod.POST},produces = "application/json; charset=utf-8")
	public String logout1(){
		try {
			String user_id = getUser_idFormSession("user_id");
			userAuditLogService.insertLog("退出", "退出", getUser_idFormSession("userName")+"退出平台", request);
			userService.logout(user_id);
			//清理session记录
			cleanSessionRecord();
		} catch (Exception e) {
			logger.error(e);
			e.printStackTrace();
		}
		
		return null;
	}
	
	
	private List<menuVo> removeDuplicate(List<menuVo> list) {
        Set<menuVo> set = new HashSet<menuVo>();
        List<menuVo> newList = new ArrayList<menuVo>();
        for (Iterator<menuVo> iter = list.iterator(); iter.hasNext();) {
			menuVo element = iter.next();
            if (set.add(element))
                newList.add(element);
        }
        return newList;
    }
	/**
	 * @Title: loginByIdCard
	 * @Description: 根据身份证号码进行登陆系统
	 * @param idcard
	 * @return
	 * @author 雒乐
	 * @return ModelAndView
	 */
	@RequestMapping(value="/loginByIdCard",method = RequestMethod.GET,produces = "application/json; charset=utf-8")
	public ModelAndView loginByIdCard(Model model, String idcard){
			ModelAndView modelAndView = new ModelAndView("redirect:/portal");
			User tempUser = null;
			User uservo=new User();
			//从cookie中取得用户
			/*User user = userService.getCurrentUser();
			if(user == null){*/
			String sessionId = request.getSession(true).getId();
			try {
				List<User> users=userService.selectByUserIdcard(idcard);
				if(users!=null && users.size()>0){
					uservo=users.get(0);
					request.setAttribute("idcard", idcard);
					userService.login(users.get(0).getUserId(),users.get(0).getPassword(),false,ClientUtil.getIP(request),sessionId);
				}else{
					request.getSession().setAttribute(ERROR_MESSAGE,"查询不到用户信息");//登录信息有误
				}
			} catch (Exception e) {
				logger.error(e);
				//登陆错误信息
				request.getSession().setAttribute(ERROR_MESSAGE, e.getMessage());//登录信息有误
				return modelAndView;
			}
			/*}else{
				request.getSession().setAttribute(ERROR_MESSAGE, "已经登录");
			}*/

			if(Constant.projectName.equals("keyCloud")){
				LicenseUtil licenseUtil = new LicenseUtil();
				try {
					Json verification = licenseUtil.getVerification(request, uservo.getUserId());
					if(!verification.isSuccess()){
						request.getSession().setAttribute(ERROR_MESSAGE,verification.getMsg());
						return modelAndView;
					}
				} catch (Exception e) {
					logger.error(e);
					request.getSession().setAttribute(ERROR_MESSAGE, e.getMessage());//登录信息有误
					return modelAndView;
				}
				
			}
			tempUser = userService.selectUserByUserId(uservo.getUserId());
			request.getSession().setAttribute("user", tempUser);
			request.getSession().setAttribute("userId", tempUser.getUserId());
			request.getSession().setAttribute("user_id", tempUser.getId());	
			request.getSession().setAttribute("userName", tempUser.getUserName());
			//存放用户密级
			request.getSession().setAttribute("uesrRankId", uservo.getUesrRankId());
			request.getSession().setAttribute("systemLevel", tempUser.getSystemLevel());
			//获取客户标识
			String  customer = numberBuilderService.getCustomerId();
				request.getSession().setAttribute("customCode", customer);
			String departName="";
			Department department= departmentService.selectByPrimaryKey(tempUser.getDepartId());
			if(department!=null){
				departName=department.getDeptName();
			}
			request.getSession().setAttribute("departName", departName);
			//密级
			UserSecret Secret = userSecretService.selectByPrimaryKey(tempUser.getId());
			if(Secret != null){
				request.getSession().setAttribute("secret", Secret.getSecret());
			}
			return modelAndView;
	}
}



